package example.com.nexd.collectionsdk.sdk.collector.core;

import android.annotation.TargetApi;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiManager;
import android.os.Build;
import android.os.Handler;
import android.os.Message;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import example.com.nexd.collectionsdk.sdk.collector.Collector;
import example.com.nexd.collectionsdk.sdk.collector.CollectorConfig;
import example.com.nexd.collectionsdk.sdk.collector.UserIdUtils;
import example.com.nexd.collectionsdk.sdk.collector.WifiCollector;
import example.com.nexd.collectionsdk.sdk.collector.bean.WifiDataResult;
import example.com.nexd.collectionsdk.sdk.collector.listener.DefaultCollectorResultListener;
import example.com.nexd.collectionsdk.sdk.collector.listener.WifiCollectorResultListener;
import example.com.nexd.collectionsdk.sdk.core.SimpleSafeTask;
import example.com.nexd.collectionsdk.sdk.core.TaskExecutor;
import example.com.nexd.collectionsdk.sdk.utils.ObjectPool;


/**
 * WifiCollectorTask create by codingfish at 15/4/29
 * TODO:
 *
 * @Version V1.0
 */
final class WifiCollectorTask extends WifiCollector {

    private WifiManager wifiManager;
    private WifiHanlder wifiHanlder;
    private List<String> wifiAddresses;
    private List<WifiDataResult> wifiDataResults;
    private WifiResultBroadcastReceiver wifiResultBroadcastReceiver;
    private WifiManager.WifiLock wifiLock;
    private ObjectPool<WifiDataResult> wifiDataResultObjectPool;

    private final static int OBJECT_POOL_SIZE = 50;

    public WifiCollectorTask(Context context, WifiCollectorResultListener wifiCollectorResultListener, CollectorConfig collectorConfig) {
        super(context, wifiCollectorResultListener, collectorConfig);

        ObjectPool.ObjectPoolFactory<WifiDataResult> wifiDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<WifiDataResult>() {
            @Override
            public WifiDataResult createObject() {
                return new WifiDataResult();
            }
        };

        wifiDataResultObjectPool = new ObjectPool<WifiDataResult>(wifiDataResultObjectPoolFactory, OBJECT_POOL_SIZE);
    }

    public WifiCollectorTask(Context context, WifiCollectorResultListener wifiCollectorResultListener) {
        super(context, wifiCollectorResultListener, null);
        ObjectPool.ObjectPoolFactory<WifiDataResult> wifiDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<WifiDataResult>() {
            @Override
            public WifiDataResult createObject() {
                return new WifiDataResult();
            }
        };

        wifiDataResultObjectPool = new ObjectPool(wifiDataResultObjectPoolFactory, OBJECT_POOL_SIZE);
    }

    public WifiCollectorTask(Context context, CollectorConfig collectorConfig) {
        super(context, null, collectorConfig);
        ObjectPool.ObjectPoolFactory<WifiDataResult> wifiDataResultObjectPoolFactory = new ObjectPool.ObjectPoolFactory<WifiDataResult>() {
            @Override
            public WifiDataResult createObject() {
                return new WifiDataResult();
            }
        };

        wifiDataResultObjectPool = new ObjectPool(wifiDataResultObjectPoolFactory, OBJECT_POOL_SIZE);
    }


    @Override
    public boolean initilazeCollector() {

        if (wifiCollectorResultListener == null) {
            wifiCollectorResultListener = DefaultCollectorResultListener.getWifiDefaultCollectorResultListener();
        }

        if (collectorConfig == null) {
            collectorConfig = new CollectorConfig.Builder().build();
        }

        if (context == null) {
            wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_CONTEXT_NULL, "context is null");
            return false;
        }

        if (!checkPermission("android.permission.ACCESS_WIFI_STATE")) {
            wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_NO_PERMISSION, "木有权限");
            return false;
        }

        wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);

        if (wifiManager == null) {
            wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_UNSUPPORTED_SENSOR_TYPE, "unsupported sensor");
            return false;
        }

        if (wifiManager.getWifiState() == WifiManager.WIFI_STATE_DISABLED) {
            //没有打开wifi
            if (collectorConfig.collector_enable_mode == Collector.bluetooth_enable_mode_auto) {
                //自动打开
                wifiManager.setWifiEnabled(true);
            } else {
                // 手动打开
                wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_SCAN_MODE_NONE, "wifi 模块不可用");
                return false;
            }
        }

        if (!(wifiManager.isWifiEnabled())) {
            //没有打开wifi
            if (collectorConfig.collector_enable_mode == Collector.bluetooth_enable_mode_auto) {
                //自动打开
                wifiManager.setWifiEnabled(true);
            } else {
                // 手动打开
                wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_SCAN_MODE_NONE, "wifi 模块不可用");
                return false;
            }
        }


        return true;
    }

    @Override
    public boolean startCollector() {
        wifiHanlder = new WifiHanlder();

        this.lockWifi();

        wifiResultBroadcastReceiver = new WifiResultBroadcastReceiver();

        context.registerReceiver(wifiResultBroadcastReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));


        // 启动采集延迟 任务， 延迟时间默认200ms
        TaskExecutor.startDelayedTask(new WifiCollectorThread(), collectorConfig.collector_delay, TimeUnit.MILLISECONDS);


        return true;
    }

    @Override
    public boolean stopCollector() {


        if (wifiResultBroadcastReceiver != null) {
            context.unregisterReceiver(wifiResultBroadcastReceiver);
            wifiResultBroadcastReceiver = null;
        }


        if (wifiHanlder != null) {
            wifiHanlder = null;
        }


        if (wifiManager != null) {
            wifiManager = null;
        }

        if (wifiCollectorResultListener != null) {
            wifiCollectorResultListener = null;
        }

        if (wifiAddresses != null) {
            wifiAddresses.clear();
        }

        if (wifiDataResults != null) {
            wifiDataResults.clear();
        }

        if (wifiLock != null) {
            this.unlockWifi();
        }
        return true;
    }


    private class WifiHanlder extends Handler {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 10010:
                    TaskExecutor.startDelayedTask(new WifiCollectorThread(), collectorConfig.collector_task_delay, TimeUnit.MILLISECONDS);
                    break;

                /*重启采集线程。重启的等待时间为原有延时的一半*/
                case 10011:
                    TaskExecutor.startDelayedTask(new WifiCollectorThread(), collectorConfig.wifi_delay / 2, TimeUnit.MILLISECONDS);
                    break;
            }
        }
    }

    private class WifiCollectorThread extends SimpleSafeTask {

        @Override
        protected Object doInBackgroundSafely() throws Exception {

            wifiAddresses = new ArrayList<String>();
            wifiDataResults = new ArrayList<WifiDataResult>();


            if (wifiManager == null) {
                wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAILED_ID_MANAGER_INIT_FAILED, "wifiManager 初始化失败");
                return null;
            }

            if (!wifiManager.isWifiEnabled()) {
                //wifi 不可用
                wifiManager.setWifiEnabled(true);
                if (wifiHanlder != null) {
                    wifiHanlder.sendEmptyMessage(10010);
                }
                return null;
            }


            wifiManager.startScan();

            if (wifiHanlder != null) {
                wifiHanlder.sendEmptyMessage(10010);
            }
            return null;
        }
    }

    private class WifiResultBroadcastReceiver extends BroadcastReceiver {


        @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
        @Override
        public void onReceive(Context context, Intent intent) {
            if (WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.equals(intent.getAction())) {

                List<ScanResult> resultList = wifiManager.getScanResults();

                if (resultList != null) {
                    //success
                    for (int i = 0, len = resultList.size(); i < len; i++) {
                        ScanResult scanResult = resultList.get(i);

                        //查重
                        if (wifiAddresses != null && !wifiAddresses.contains(scanResult.BSSID)) {
                            WifiDataResult wifiDataResult = new WifiDataResult();
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
                                wifiDataResult.setTimestamp(scanResult.timestamp);
                            } else {
                                wifiDataResult.setTimestamp(0);
                            }
                            wifiDataResult.setId(UserIdUtils.getInstance().getTask_Id());
                            wifiDataResult.setBssid(scanResult.BSSID);
                            wifiDataResult.setCapability(scanResult.capabilities);
                            wifiDataResult.setFrequency(scanResult.frequency);
                            wifiDataResult.setLevel(scanResult.level);
                            wifiDataResult.setSingleIntensity(WifiManager.calculateSignalLevel(scanResult.level, 100));
                            wifiDataResult.setSsid(scanResult.SSID);
                            wifiDataResult.setUserId(UserIdUtils.getInstance().getUserId(context));
                            wifiDataResults.add(wifiDataResult);
//                            wifiDataResultObjectPool.free(wifiDataResult);

                            wifiAddresses.add(scanResult.BSSID);
                        }
                    }

                    if (wifiDataResults != null && wifiCollectorResultListener != null) {
                        wifiCollectorResultListener.onSuccess(UserIdUtils.getInstance().getTask_Id(), wifiDataResults);
                    } else {
                        if (wifiCollectorResultListener != null) {
                            wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_RESULT_NULL, "没有结果");
                        }
                    }
                } else {
                    if (wifiCollectorResultListener != null) {
                        wifiCollectorResultListener.onFailed(UserIdUtils.getInstance().getTask_Id(), Collector.FAIED_ID_RESULT_NULL, "没有结果");
                    }
                }

                //
                resultList.clear();
                resultList = null;
            }
        }
    }

    private void lockWifi() {

        wifiLock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, "nexd_collector_wifi_lock_tag");
        if (null != wifiLock && !wifiLock.isHeld()) {
            wifiLock.acquire();
        }
    }

    private void unlockWifi() {
        if (null != wifiLock && wifiLock.isHeld()) {
            wifiLock.release();
        }
    }
}
